package com.duobaoyu.dby.supply.biz.strategy.message.delay;

import cn.hutool.core.lang.Pair;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.duobaoyu.dby.channel.adapter.enums.biz.order.OrderStatusEnum;
import com.duobaoyu.dby.channel.common.util.SupplyCollectionUtils;
import com.duobaoyu.dby.common.mybatis.util.EnumUtils;
import com.duobaoyu.dby.supply.biz.client.boundary.order.OrderBoundaryClient;
import com.duobaoyu.dby.supply.biz.client.boundary.order.bean.bo.OrderBO;
import com.duobaoyu.dby.supply.biz.client.boundary.order.bean.bo.OrderQueryInBO;
import com.duobaoyu.dby.supply.biz.client.boundary.order.bean.bo.UpdateOrderBO;
import com.duobaoyu.dby.supply.biz.constant.OperateSourceConstants;
import com.duobaoyu.dby.supply.biz.constant.OrderOperateConstants;
import com.duobaoyu.dby.supply.biz.producer.message.OrderPaymentTimeoutCancelMessage;
import com.duobaoyu.dby.supply.biz.service.order.OrderService;
import com.duobaoyu.dby.supply.biz.service.queue.core.DistributionQueueMessage;
import com.duobaoyu.dby.supply.biz.service.queue.service.AbstractDistributionQueueJobConsumer;
import com.duobaoyu.dby.supply.common.biz.bo.order.CancelOrderInBO;
import com.duobaoyu.dby.supply.common.biz.bo.order.CancelOrderOutBO;
import com.duobaoyu.dby.supply.core.dinger.annotation.DingerTalk;
import com.google.common.collect.Lists;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * @author chenms
 * @date 2023/11/10 5:35 PM
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class DelayCancelPaymentTimeoutOrderDistributionQueueJobConsumer extends AbstractDistributionQueueJobConsumer {

    @Value("${delay.cancelPaymentTimeoutOrder.topicName}")
    private String topicName;

    private final OrderBoundaryClient orderBoundaryClient;
    private final OrderService orderService;

    @Override
    public String topicName() {
        return topicName;
    }

    @Override
    @DingerTalk(title = "支付超时取消延迟消息")
    public void consume(DistributionQueueMessage distributionQueueMessage) {
        if(log.isDebugEnabled()) {
            log.debug("收到支付超时取消消息: {}", JSON.toJSONString(distributionQueueMessage));
        }
        String data = distributionQueueMessage.getData();
        OrderPaymentTimeoutCancelMessage paymentTimeoutCancelMessage = JSONObject.parseObject(data, OrderPaymentTimeoutCancelMessage.class);
        String orderSn = paymentTimeoutCancelMessage.getOrderSn();
        List<OrderBO> list = orderService.list(OrderQueryInBO.builder().orderSnList(Lists.newArrayList(orderSn)).build());
        if (CollectionUtils.isEmpty(list)) {
            if(log.isDebugEnabled()) {
                log.debug("支付超时取消消息处理结束, 未查询到相关的订单: orderSn={}", orderSn);
            }
            return;
        }
        OrderBO order = SupplyCollectionUtils.getSingleData(list);
        if (EnumUtils.neq(OrderStatusEnum.WAIT_PAY, order.getOrderStatus())) {
            if(log.isDebugEnabled()) {
                log.debug("支付超时取消消息处理结束, 订单状态不是待支付: orderSn={}, status={}", orderSn, order.getOrderStatus());
            }
            return;
        }
        UpdateOrderBO updateOrder = new UpdateOrderBO();
        updateOrder.setOrderSn(orderSn);
        updateOrder.setOrderStatus(Pair.of(order.getOrderStatus(), OrderStatusEnum.CANCEL.getValue()));
        updateOrder.setCancelReason(OrderOperateConstants.PAY_TIMEOUT_SYSTEM_AUTO_CANCEL);
        updateOrder.setDescription(OrderOperateConstants.PAY_TIMEOUT_SYSTEM_AUTO_CANCEL);
        updateOrder.setSource(OperateSourceConstants.SYSTEM);
        updateOrder.setLogChangeItemList(order.diff(updateOrder).getDiffs());
        boolean result = orderService.updateOrderByOrderSn(updateOrder);
        log.info("更新订单状态为取消结果: {}", result);
        if(result) {
            CancelOrderInBO cancelOrderIn = CancelOrderInBO.builder()
                    .orderSn(order.getOrderSn())
                    .orderTradeSn(order.getOrderTradeSn())
                    .orderStatus(order.getOrderStatus())
                    .channelTradeOrderSn(order.getChannelTradeOrderSn())
                    .cancelReason(OrderOperateConstants.PAY_TIMEOUT_SYSTEM_AUTO_CANCEL)
                    .channelCode(order.getChannelCode())
                    .build();
            if(log.isDebugEnabled()) {
                log.debug("开始取消渠道订单: {}", cancelOrderIn);
            }
            CancelOrderOutBO cancelOrderOut = orderBoundaryClient.batchCancelOrder(Lists.newArrayList(cancelOrderIn));
            log.info("取消渠道订单结果: {}", cancelOrderOut);
        }
        log.info("支付超时取消消息处理结束: {}", orderSn);
    }
}
